﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;

namespace FrogEngine
{
	public class GameContentService : GameEntityServiceBase<IHasContent>
	{
		public GameContentService(IEngine engine)
			: base(engine)
		{
			managerMap = new Dictionary<Type, ContentManager>();
			assetMap = new Dictionary<string, List<Type>>();
			referenceCounts = new Dictionary<Type, int>();
			serviceOrder = 1;
		}

		private Dictionary<Type, ContentManager> managerMap;
		private Dictionary<string, List<Type>> assetMap;
		private Dictionary<Type, int> referenceCounts;

		public ContentManager GlobalManager
		{
			get { return Engine.ContentManager; }
		}

		public override bool Subscribe(IGameEntity entity)
		{
			if (base.Subscribe(entity))
			{
				var contentEntity = entity as IHasContent;
				Type t = contentEntity.GetType();

				if (referenceCounts.ContainsKey(t))
					referenceCounts[t]++;
				else
				{
					managerMap.Add(t, new ContentManager(GlobalManager.ServiceProvider) { RootDirectory = "Content" });
					referenceCounts.Add(t, 1);
				}

				contentEntity.ContentManager = managerMap[t];

				foreach (var assetName in contentEntity.AssetNames())
				{
					if (assetMap.ContainsKey(assetName))
					{
						if (!assetMap[assetName].Contains(t))
							assetMap[assetName].Add(t);
					}
					else
					{
						var list = new List<Type>();
						list.Add(t);
						assetMap.Add(assetName, list);
					}
				}
				contentEntity.LoadContent();
				return true;
			}
			else
				return false;
		}

		public override bool Unsubscribe(IGameEntity entity)
		{
			if (base.Unsubscribe(entity))
			{
				var contentEntity = entity as IHasContent;
				Type t = contentEntity.GetType();

				referenceCounts[t]--;
				if (referenceCounts[t] == 0)
					managerMap[t].Unload();
				return true;
			}
			else
				return false;
		}

		public void Update(GameTime gameTime)
		{
		}
	}
}
